import React, { useState, useEffect } from 'react';
import { useNavigate } from 'react-router-dom';
import {
  Form,
  Input,
  Button,
  Card,
  Typography,
  Space,
  Modal,
  Upload,
  message,
  Row,
  Col,
  Select,
} from 'antd';
import {
  PlusOutlined,
  UploadOutlined,
  UserOutlined,
  EditOutlined,
  DeleteOutlined,
  CopyOutlined,
} from '@ant-design/icons';
//样式库
import styled from 'styled-components';
import type { UploadFile } from 'antd/es/upload/interface';
import type { RcFile } from 'antd/es/upload';
//HTTP请求库
import axios from 'axios';
import { votingFactoryAbi, votingFactoryAddress } from "../chain/votingFactory";
//以太坊交互库
import { ethers } from "ethers";

//定义样式,方便后续修改,解构 Ant Design 组件
const { Title, Text } = Typography;
const { TextArea } = Input;
const { Option } = Select;

//定义 Candidate 接口，描述候选人的数据结构
interface Candidate {
  id: string;
  name: string;
  signature?: string;
  imageUrl?: string;
}

//定义容器样式,使用 styled-components 创建自定义样式的组件
const CreateVoteContainer = styled.div`
  padding: 24px;
  max-width: 1200px;
  margin: 0 auto;
`;

const CandidateCard = styled(Card)`
  margin-bottom: 16px;
  .ant-card-body {
    display: flex;
    align-items: center;
    gap: 16px;
    justify-content: space-between;
    position: relative;
  }
`;

const CandidateInfo = styled.div`
  display: flex;
  flex-direction: column;
  gap: 8px;
  flex-grow: 1;
`;

const ActionButtons = styled.div`
  position: absolute;
  right: 16px;
  top: 50%;
  transform: translateY(-50%);
  display: flex;
  gap: 8px;
  background: rgba(255, 255, 255, 0.8);
  padding: 4px 8px;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.1);
`;

function generateInviteCode() {
  const chars = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789';
  let code = '';
  for (let i = 0; i < 16; i++) {
    code += chars.charAt(Math.floor(Math.random() * chars.length));
  }
  return code.match(/.{1,4}/g)?.join(' ') || code;
}

const CreateVote: React.FC = () => {
  //创建表单
  const [form] = Form.useForm();
  const [modalForm] = Form.useForm();
  const navigate = useNavigate();
  const [candidates, setCandidates] = useState<Candidate[]>([]);
  const [isModalVisible, setIsModalVisible] = useState(false);
  const [fileList, setFileList] = useState<UploadFile[]>([]);
  const [hoveredCandidateId, setHoveredCandidateId] = useState<string | null>(null);
  const [editingCandidateId, setEditingCandidateId] = useState<string | null>(null);
  const [candidateType, setCandidateType] = useState<'person' | 'place' | 'plan' | 'other'>('person');
  const [inviteCode, setInviteCode] = useState('');
  const [inviteModalVisible, setInviteModalVisible] = useState(false);
  const [expireValue, setExpireValue] = useState<number>(1);
  const [expireUnit, setExpireUnit] = useState<'second' | 'minute' | 'hour'>('hour');
  const [pendingVoteName, setPendingVoteName] = useState('');
  const [createLoading, setCreateLoading] = useState(false);
  const [maxVoters, setMaxVoters] = useState<number>(0);

  //监听正在编辑的候选人ID变化
  useEffect(() => {
    if (editingCandidateId !== null) {
      const candidateToEdit = candidates.find(c => c.id === editingCandidateId);
      if (candidateToEdit) {
        form.setFieldsValue({
          candidateName: candidateToEdit.name,
          candidateSignature: candidateToEdit.signature,
        });
        if (candidateToEdit.imageUrl) {
          setFileList([{
            uid: '-1',
            name: 'image.png',
            status: 'done',
            url: candidateToEdit.imageUrl,
          } as UploadFile]);
        } else {
          setFileList([]);
        }
      }
    } else {
      form.resetFields(['candidateName', 'candidateSignature']);
      setFileList([]);
    }
  }, [editingCandidateId, candidates, form]);

  const handleTypeChange = (value: 'person' | 'place' | 'plan' | 'other') => {
    setCandidateType(value);
    setCandidates([]);
    setEditingCandidateId(null);
    setFileList([]);
  };

  const voteNameValue = Form.useWatch('voteName', form);

  //添加候选逻辑
  const handleAddCandidate = () => {
    if (!voteNameValue) {
      message.warning('请先填写投票名称');
      return;
    }
    setEditingCandidateId(null);
    setIsModalVisible(true);
    modalForm.resetFields();
    setFileList([]);
  };
// 处理添加或编辑候选人逻辑
  const handleModalOk = (values: any) => {
    //处理图片URL,创建了一个指向内存中文件的临时URL,这个URL只在当前页面会话有效，浏览器关闭后失效
    //这是一个本地URL（blob:开头），不是真正的网络地址
    //你看到的是浏览器提供的本地预览功能，不是图片被上传到了服务器
    const imageUrl = fileList.length > 0 && fileList[0].originFileObj ? URL.createObjectURL(fileList[0].originFileObj as Blob)
                 : fileList.length > 0 && fileList[0].url ? fileList[0].url
                 : undefined;

    if (editingCandidateId !== null) {
      setCandidates(candidates.map(candidate =>
        candidate.id === editingCandidateId
          ? { ...candidate, name: values.candidateName, signature: values.candidateSignature, imageUrl: imageUrl }
          : candidate
      ));
      message.success('候选信息更新成功！');
    } else {
      if (!values.candidateName) {
        message.error('请输入候选人姓名');
        return;
      }
      const newCandidate: Candidate = {
        id: Date.now().toString(),
        name: values.candidateName,
        signature: values.candidateSignature,
        imageUrl: imageUrl,
      };
      setCandidates([...candidates, newCandidate]);
      message.success('候选添加成功！');
    }

    setIsModalVisible(false);
    setEditingCandidateId(null);
    modalForm.resetFields();
    setFileList([]);
  };

  const handleModalCancel = () => {
    setIsModalVisible(false);
    setEditingCandidateId(null);
    form.resetFields(['candidateName', 'candidateSignature']);
    setFileList([]);
    modalForm.resetFields();
  };

  // 处理上传文件逻辑
  const beforeUpload = (file: RcFile) => {
    const isImage = file.type.startsWith('image/');
    if (!isImage) {
      message.error('只能上传图片文件！');
    }
    const isLt2M = file.size / 1024 / 1024 < 2;
    if (!isLt2M) {
      message.error('图片大小不能超过 2MB！');
    }
    return isImage && isLt2M ? false : Upload.LIST_IGNORE;
  };

  //处理文件上传变化
  const handleUploadChange = ({ fileList: newFileList }: { fileList: UploadFile[] }) => {
    setFileList(newFileList.filter(file => file.status !== 'removed'));
  };

  const handleDeleteCandidate = (id: string) => {
    setCandidates(candidates.filter(candidate => candidate.id !== id));
    message.success('候选删除成功！');
  };

  //修改候选
  const handleModifyCandidate = (candidate: Candidate) => {
    if (!voteNameValue) {
      message.warning('请先填写投票名称');
      return;
    }
    setEditingCandidateId(candidate.id);
    setIsModalVisible(true);
    modalForm.setFieldsValue({
      candidateName: candidate.name,
      candidateSignature: candidate.signature,
    });
    if (candidate.imageUrl) {
      setFileList([{
        uid: '-1',
        name: 'image.png',
        status: 'done',
        url: candidate.imageUrl,
      } as UploadFile]);
    } else {
      setFileList([]);
    }
  };


  //创建投票
  const handleCreateVote = async (values: { voteName: string }) => {
    if (candidates.length === 0) {
      message.warning('请至少添加一位候选');
      return;
    }
    if (maxVoters <= 0) {
      message.warning('请设置投票人数限制');
      return;
    }
    setCreateLoading(true);
    try {
      // 1. 先链上创建投票
      await (window as any).ethereum.request({ method: "eth_requestAccounts" });
      const provider = new ethers.BrowserProvider((window as any).ethereum);
      const signer = await provider.getSigner();
      const contract = new ethers.Contract(
        votingFactoryAddress,
        votingFactoryAbi,
        signer
      );
      const tx = await contract.createVote(
        values.voteName,
        candidates.map(c => [c.name, c.signature || "", c.imageUrl || ""]),
        maxVoters
      );
      message.info("等待链上交易确认...");
      const receipt = await tx.wait();

      // 解析 chainVoteId
      const event = receipt.logs.find((log: any) =>
        log.topics && log.topics[0] === "0x70471025a22047b42e8cf3fb05767d633c780d99f80e6ba9057b8d15b15cef67"
      );
      if (!event) throw new Error('未找到VoteCreated事件，请检查合约是否正确部署');
      const data = event.data;
      const chainVoteId = parseInt(data.slice(2, 66), 16);

      // 2. 再链下创建投票
      const token = localStorage.getItem('token');
      let expireSeconds = expireValue;
      if (expireUnit === 'minute') expireSeconds = expireValue * 60;
      if (expireUnit === 'hour') expireSeconds = expireValue * 3600;
      const code = generateInviteCode();

      const res = await axios.post('/api/vote/create', {
        voteName: values.voteName,
        candidates: candidates.map(c => ({
          name: c.name,
          signature: c.signature,
          imageUrl: c.imageUrl
        })),
        inviteCode: code.replace(/\s/g, ''),
        expireSeconds,
        maxVoters,
        chainVoteId // 直接存入
      }, {
        headers: { Authorization: `Bearer ${token}` }
      });

      if (!res.data.success) {
        message.error(res.data.message || '创建投票失败');
        return;
      }

      setInviteCode(code);
      setInviteModalVisible(true);

    } catch (error: any) {
      message.error(error.message || '创建投票失败');
    } finally {
      setCreateLoading(false);
    }
  };

  const handleConfirmInvite = () => {
    setInviteModalVisible(false);
    navigate('/main');
  };

  const renderModalFields = () => {
    switch (candidateType) {
      case 'person':
        return (
          <>
            <Form.Item
              name="candidateName"
              label="姓名"
              rules={[{ required: true, message: '请输入候选人姓名' }]}
            >
              <Input placeholder="候选人姓名" />
            </Form.Item>
            <Form.Item name="candidateSignature" label="个性签名（可选）">
              <TextArea placeholder="个性签名（可选）" />
            </Form.Item>
            <Form.Item label="上传照片（可选）">
              <Upload
                listType="picture"
                maxCount={1}
                beforeUpload={beforeUpload}
                onChange={handleUploadChange}
                fileList={fileList}
                onRemove={(file) => {
                  setFileList(fileList.filter(item => item.uid !== file.uid));
                  if (editingCandidateId !== null) {
                      setCandidates(candidates.map(candidate =>
                         candidate.id === editingCandidateId
                           ? { ...candidate, imageUrl: undefined }
                           : candidate
                       ));
                  }
                }}
              >
                {!(editingCandidateId !== null && fileList.length > 0) && (
                  <Button icon={<UploadOutlined />}>上传照片</Button>
                )}
              </Upload>
            </Form.Item>
          </>
        );
      case 'place':
        return (
          <>
            <Form.Item
              name="candidateName"
              label="活动地点名称"
              rules={[{ required: true, message: '请输入活动地点名称' }]}
            >
              <Input placeholder="活动地点名称" />
            </Form.Item>
            <Form.Item name="candidateSignature" label="地点介绍（可选）">
              <TextArea placeholder="地点介绍（可选）" />
            </Form.Item>
            <Form.Item label="上传地点图片（可选）">
              <Upload
                listType="picture"
                maxCount={1}
                beforeUpload={beforeUpload}
                onChange={handleUploadChange}
                fileList={fileList}
                onRemove={(file) => {
                  setFileList(fileList.filter(item => item.uid !== file.uid));
                  if (editingCandidateId !== null) {
                      setCandidates(candidates.map(candidate =>
                         candidate.id === editingCandidateId
                           ? { ...candidate, imageUrl: undefined }
                           : candidate
                       ));
                  }
                }}
              >
                {!(editingCandidateId !== null && fileList.length > 0) && (
                  <Button icon={<UploadOutlined />}>上传图片</Button>
                )}
              </Upload>
            </Form.Item>
          </>
        );
      case 'plan':
        return (
          <>
            <Form.Item
              name="candidateName"
              label="方案名称"
              rules={[{ required: true, message: '请输入方案名称' }]}
            >
              <Input placeholder="方案名称" />
            </Form.Item>
            <Form.Item name="candidateSignature" label="负责人/组（可选）">
              <Input placeholder="负责人/组（可选）" />
            </Form.Item>
            <Form.Item name="candidateDesc" label="方案介绍（可选）">
              <TextArea placeholder="方案介绍（可选）" />
            </Form.Item>
            <Form.Item label="上传文件（可选）">
              <Upload
                maxCount={1}
                beforeUpload={beforeUpload}
                onChange={handleUploadChange}
                fileList={fileList}
                onRemove={(file) => {
                  setFileList(fileList.filter(item => item.uid !== file.uid));
                  if (editingCandidateId !== null) {
                      setCandidates(candidates.map(candidate =>
                         candidate.id === editingCandidateId
                           ? { ...candidate, imageUrl: undefined }
                           : candidate
                       ));
                  }
                }}
              >
                {!(editingCandidateId !== null && fileList.length > 0) && (
                  <Button icon={<UploadOutlined />}>上传文件</Button>
                )}
              </Upload>
            </Form.Item>
          </>
        );
      case 'other':
        return (
          <>
            <Form.Item
              name="candidateName"
              label="名称"
              rules={[{ required: true, message: '请输入名称' }]}
            >
              <Input placeholder="名称" />
            </Form.Item>
            <Form.Item name="candidateSignature" label="介绍（可选）">
              <TextArea placeholder="介绍（可选）" />
            </Form.Item>
            <Form.Item label="上传图片（可选）">
              <Upload
                listType="picture"
                maxCount={1}
                beforeUpload={beforeUpload}
                onChange={handleUploadChange}
                fileList={fileList}
                onRemove={(file) => {
                  setFileList(fileList.filter(item => item.uid !== file.uid));
                  if (editingCandidateId !== null) {
                      setCandidates(candidates.map(candidate =>
                         candidate.id === editingCandidateId
                           ? { ...candidate, imageUrl: undefined }
                           : candidate
                       ));
                  }
                }}
              >
                {!(editingCandidateId !== null && fileList.length > 0) && (
                  <Button icon={<UploadOutlined />}>上传图片</Button>
                )}
              </Upload>
            </Form.Item>
          </>
        );
      default:
        return null;
    }
  };

  return (
    <CreateVoteContainer>
      <Card>
        <Form
          form={form}
          layout="vertical"
          onFinish={handleCreateVote}
          onFinishFailed={(err) => { console.log('主表单校验失败', err); }}
        >
          <Form.Item
            name="voteName"
            label="投票名称"
            rules={[{ required: true, message: '请输入投票名称' }]}
          >
            <Input placeholder="请输入投票名称" />
          </Form.Item>

          <Form.Item label="投票人数限制">
            <Input
              type="number"
              min={1}
              value={maxVoters}
              onChange={e => setMaxVoters(Number(e.target.value))}
              style={{ width: 200 }}
              placeholder="请输入最大投票人数"
            />
          </Form.Item>

          <Form.Item label="邀请码有效期">
            <Input
              type="number"
              min={1}
              value={expireValue}
              onChange={e => setExpireValue(Number(e.target.value))}
              style={{ width: 120, marginRight: 8 }}
              placeholder="请输入数值"
            />
            <Select
              value={expireUnit}
              style={{ width: 100 }}
              onChange={v => setExpireUnit(v)}
            >
              <Select.Option value="second">秒</Select.Option>
              <Select.Option value="minute">分钟</Select.Option>
              <Select.Option value="hour">小时</Select.Option>
            </Select>
          </Form.Item>

          <Row align="middle" style={{ marginBottom: 16 }}>
            <Col>
              <Title level={4} style={{ margin: 0 }}>候选列表</Title>
            </Col>
            <Col>
              <Select
                value={candidateType}
                style={{ width: 120, marginLeft: 16 }}
                onChange={handleTypeChange}
              >
                <Option value="person">人</Option>
                <Option value="place">地点</Option>
                <Option value="plan">方案</Option>
                <Option value="other">其他</Option>
              </Select>
            </Col>
          </Row>

          {candidates.length === 0 ? (
            <div style={{ textAlign: 'center', marginBottom: 24 }}>
              <Text type="secondary">暂无候选，请点击下方按钮添加</Text>
            </div>
          ) : (
            candidates.map((candidate) => (
              <CandidateCard
                key={candidate.id}
                onMouseEnter={() => setHoveredCandidateId(candidate.id)}
                onMouseLeave={() => setHoveredCandidateId(null)}
              >
                {candidate.imageUrl ? (
                  <img
                    src={candidate.imageUrl}
                    alt={candidate.name}
                    style={{ width: 50, height: 50, objectFit: 'cover', borderRadius: '50%' }}
                  />
                ) : (
                  <UserOutlined style={{ fontSize: 30 }} />
                )}
                <CandidateInfo>
                  <Text strong>{candidate.name}</Text>
                  {candidate.signature && (
                    <Text type="secondary">{candidate.signature}</Text>
                  )}
                </CandidateInfo>
                {hoveredCandidateId === candidate.id && (
                  <ActionButtons>
                    <Button
                      type="text"
                      icon={<EditOutlined />}
                      onClick={() => handleModifyCandidate(candidate)}
                      title="修改"
                    />
                    <Button
                      type="text"
                      danger
                      icon={<DeleteOutlined />}
                      onClick={() => handleDeleteCandidate(candidate.id)}
                      title="删除"
                    />
                  </ActionButtons>
                )}
              </CandidateCard>
            ))
          )}

          <Button
            type="dashed"
            onClick={handleAddCandidate}
            icon={<PlusOutlined />}
            style={{ width: '100%', marginBottom: 24 }}
          >
            添加候选
          </Button>

          <Form.Item>
            <Button type="primary" htmlType="submit" block loading={createLoading}>
              生成投票
            </Button>
          </Form.Item>
        </Form>
      </Card>

      <Modal
        title={editingCandidateId !== null
          ? (candidateType === 'person' ? '修改候选人'
            : candidateType === 'place' ? '修改候选地点'
            : candidateType === 'plan' ? '修改候选方案'
            : '修改其他')
          : (candidateType === 'person' ? '添加候选人'
            : candidateType === 'place' ? '添加候选地点'
            : candidateType === 'plan' ? '添加候选方案'
            : '添加其他')
        }
        open={isModalVisible}
        onOk={() => modalForm.submit()}
        onCancel={handleModalCancel}
        okText={editingCandidateId !== null ? "保存" : "确定"}
        cancelText="取消"
      >
        <Form
          form={modalForm}
          layout="vertical"
          onFinish={handleModalOk}
          onFinishFailed={(err) => { console.log('弹窗表单校验失败', err); }}
        >
          {renderModalFields()}
        </Form>
      </Modal>

      <Modal
        open={inviteModalVisible}
        title="邀请码"
        footer={[
          <Button key="confirm" type="primary" onClick={handleConfirmInvite}>
            确认
          </Button>
        ]}
        onCancel={() => {
          setInviteModalVisible(false);
          navigate('/main');
        }}
        destroyOnClose
      >
        <div style={{ textAlign: 'center' }}>
          <Title level={4}>请妥善保存此邀请码</Title>
          <Text type="secondary">邀请码仅显示一次，丢失无法找回！</Text>
          <div style={{
            margin: '24px 0 16px 0',
            display: 'flex',
            alignItems: 'center',
            justifyContent: 'center'
          }}>
            <div style={{
              fontSize: 24,
              letterSpacing: 2,
              background: '#f5f5f5',
              borderRadius: 8,
              padding: '12px 24px',
              fontFamily: 'monospace',
              userSelect: 'all',
              minWidth: 220
            }}>
              {inviteCode}
            </div>
            <Button
              style={{ marginLeft: 12 }}
              icon={<CopyOutlined />}
              onClick={() => {
                navigator.clipboard.writeText(inviteCode.replace(/\s/g, ''));
                message.success('邀请码已复制');
              }}
            >
              复制
            </Button>
          </div>
          <Text type="secondary" style={{ color: '#faad14' }}>
            有效期：{expireValue} {expireUnit === 'second' ? '秒' : expireUnit === 'minute' ? '分钟' : '小时'}，过期后需重新创建投票
          </Text>
        </div>
      </Modal>
    </CreateVoteContainer>
  );
};

export default CreateVote; 